package com.javasm.security;

import com.javasm.commons.util.SpringUtil;
import com.javasm.sys.LoginUser;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class JwtTokenAuthenticationFilter extends OncePerRequestFilter {

    private static TokenService tokenService;

    @Override
    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse resp, FilterChain filterChain) throws ServletException, IOException {
        if(tokenService==null)tokenService= SpringUtil.getBean(TokenService.class);
        LoginUser u = tokenService.getLoginUser(req);//从请求头获取admin_token，进行解析后，从redis获取对应的LoginUser

        if(u!=null){
            //刷新token
            tokenService.refreshToken(u);
            //创建Authentication认证对象对象，保存线程变量
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(u, null, u.getAuthorities());
            authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(req));
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        }

        //如果u是null，不能像之前一样抛出未登录异常，因为必定有security的一些匿名请求，也会走这个过滤器，要保持继续执行。
        //一直到最后FilterSecurityInterceptor过滤器对需要认证才能访问的资源，在未认证通过时候抛出异常，再进行处理
        filterChain.doFilter(req,resp);
    }
}
